package com.springboot.uav.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.springboot.uav.dto.MyOrdersQueryDto;
import com.springboot.uav.dto.OrderQueryDto;
import com.springboot.uav.dto.OrdersDto;
import com.springboot.uav.entity.*;
import com.springboot.uav.mapper.OrdersMapper;
import com.springboot.uav.mapper.UserMapper;
import com.springboot.uav.service.OrdersService;
import com.springboot.uav.service.UserService;
import com.springboot.uav.util.AliOSSUtils;
import com.springboot.uav.util.OcrUtil;
import com.springboot.uav.util.RewardUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import net.sourceforge.tess4j.TesseractException;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
@RequiredArgsConstructor//注入必须初始化的值，final
public class OrdersServiceImpl extends ServiceImpl<OrdersMapper, Orders> implements OrdersService {

    private final OrdersMapper ordersMapper;

    private final RewardUtil rewardUtil;

    private final UserMapper userMapper;

    private final AliOSSUtils aliOSSUtils;

    private final OcrUtil ocrUtil;

    //缓存下单人id和下单时间
    ConcurrentHashMap<Integer, Long> orderTimestampCache = new ConcurrentHashMap<>();

    @Override
    public Result getReward(OrdersDto ordersDto) {
        if(ordersDto==null){
            return Result.error(400,"未填写相关信息");
        }
        if(ordersDto.getPickupAddress()==null||ordersDto.getPickupAddress()==""){
            return Result.error(1001,"取件地址为空，请填写取件地址");
        }
        if(ordersDto.getDeliveryAddress()==null||ordersDto.getDeliveryAddress()==""){
            return Result.error(1002,"收件地址为空，请填写收件地址");
        }
        if(ordersDto.getPhoneNumber()==null||ordersDto.getPhoneNumber()==""){
            return Result.error(1003,"联系方式为空，请填写联系方式");
        }
        //总数
        int num=ordersDto.getSmallNum()+ordersDto.getMediumNum()+ordersDto.getBigNum();
        if(num==0){
            return Result.error(1004,"包裹数量为空，请添加包裹");
        }
        //处理取件码
        String[] codeArray=ordersDto.getCode().split(",");
        if(codeArray.length==0||ordersDto.getCode()==null||ordersDto.getCode()==""){
            return Result.error(10005,"取件码为空，请添加取件码");
        }
        if(num!=codeArray.length){
            return Result.error(1006,"包裹数量和取件码数量不符合，请核对");
        }
        //报酬
        double reward=rewardUtil.Calculate(ordersDto.getSmallNum(),ordersDto.getMediumNum(),ordersDto.getBigNum());
        if(userMapper.getBalanceById(ordersDto.getCustomerId()) <reward){
            return Result.error(1007,"余额不足，请及时充值");
        }
        orderTimestampCache.put(ordersDto.getCustomerId(), System.currentTimeMillis()); // 记录生成时间
        //满足下单条件,返回报酬
        return Result.success(reward);
    }

    @Override
    public Result addOrderImage(MultipartFile image) throws IOException, TesseractException {
        if(image==null){
            return Result.error(400,"图片上传失败");
        }
        String url=aliOSSUtils.upload(image);
        List<String>codes= ocrUtil.extractCodeFromImageUrl(url);
        if(codes==null||codes.size()==0){
            return Result.error(1000,"未能识别取件码，请重新上传图片");
        }
        return Result.success(codes);
    }

    @Override
    public Result addOrder(OrdersDto ordersDto) {
        //报酬
        double reward=rewardUtil.Calculate(ordersDto.getSmallNum(),ordersDto.getMediumNum(),ordersDto.getBigNum());
        Long orderTimestamp = orderTimestampCache.get(ordersDto.getCustomerId()); // 获取order时间
        if(orderTimestamp==null||System.currentTimeMillis() - orderTimestamp>60000){
            //清除缓存
            orderTimestampCache.remove(ordersDto.getCustomerId());
            return Result.error(400,"支付超时，请重新下单");
        }
        //清除缓存
        orderTimestampCache.remove(ordersDto.getCustomerId());
        //下单成功
        Orders order=new Orders()
                .setCustomerId(ordersDto.getCustomerId())
                .setPhoneNumber(ordersDto.getPhoneNumber())
                .setDescription(ordersDto.getDescription())
                .setCode(ordersDto.getCode())
                .setPickupAddress(ordersDto.getPickupAddress())
                .setDeliveryAddress(ordersDto.getDeliveryAddress())
                .setSmallNum(ordersDto.getSmallNum())
                .setMediumNum(ordersDto.getMediumNum())
                .setBigNum(ordersDto.getBigNum())
                .setReward(new BigDecimal(reward));
        ordersMapper.insert(order);
        //扣余额
        userMapper.deductionBalance(reward,ordersDto.getCustomerId());
        return Result.success(200,"下单成功已付款");
    }

    @Override
    public Result orderQuery(OrderQueryDto orderQueryDto) {
        String pickupFilter = orderQueryDto.getPickupFilter(); //取件筛选
        String deliveryFilter = orderQueryDto.getDeliveryFilter();//收件筛选
        Page<PublicOrdersQueryMsg> page = new Page<>(orderQueryDto.getPage(),orderQueryDto.getSize());

        IPage<PublicOrdersQueryMsg> pageResult = ordersMapper.selectOrdersWithFilters(page, pickupFilter,deliveryFilter);
        // 获取分页查询结果中的数据
        List<PublicOrdersQueryMsg> orderList = pageResult.getRecords();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (PublicOrdersQueryMsg orderEntity : orderList) {
            try {
                orderEntity.setTimeAgo(timeAgo(formatter.parse(orderEntity.getTimeAgo())));// 示例，实际需要计算
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
        OrderQuerySuccess orderQuerySuccess = new OrderQuerySuccess();
        orderQuerySuccess.setOrders(orderList).setTotalPages(pageResult.getPages()).setTotalCount( pageResult.getTotal());
        return new Result(200,"查询成功",orderQuerySuccess);
    }

    @Override
    public Result myOrdersFind(MyOrdersQueryDto myOrdersQueryDto) {
        String filter = myOrdersQueryDto.getFilterString();//搜索条件
        Integer userId = myOrdersQueryDto.getUserId();
        Integer type = myOrdersQueryDto.getOrdersType();
        Page<PrivateOrdersQueryMsg> page = new Page<>(myOrdersQueryDto.getPage(),myOrdersQueryDto.getSize());
        //查询
        IPage<PrivateOrdersQueryMsg> pageResult = ordersMapper.selectMyOrdersWithFilters(page,userId,type,filter);
        // 获取分页查询结果中的数据
        List<PrivateOrdersQueryMsg> orderList = pageResult.getRecords();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (PrivateOrdersQueryMsg orderEntity : orderList) {
            try {
                orderEntity.setTimeAgo(timeAgo(formatter.parse(orderEntity.getTimeAgo())));// 需要计算
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
        }
        MyOrderQuerySuccess myOrderQuerySuccess = new MyOrderQuerySuccess();
        myOrderQuerySuccess.setOrders(orderList).setTotalPages(pageResult.getPages()).setTotalCount( pageResult.getTotal());
        return new Result(200,"查询成功",myOrderQuerySuccess);
    }

    @Override
    public boolean getOrder(Integer userId, Integer orderId) {
        //设置
        UpdateWrapper<Orders> ordersUpdateWrapper = new UpdateWrapper<>();
        ordersUpdateWrapper.eq("order_id",orderId);
        //更新实体
        Orders orders = new Orders();
        orders.setCourierId(userId).setOrderStatus(1);
        //更新结果
        return this.update(orders,ordersUpdateWrapper);
    }

    private String timeAgo(Date orderDate) {
        long currentTime = System.currentTimeMillis();  // 获取当前时间的毫秒数
        long orderTime = orderDate.getTime();  // 获取订单时间的毫秒数

        long diffInMillis = currentTime - orderTime;  // 时间差（毫秒）

        long diffInSeconds = TimeUnit.MILLISECONDS.toSeconds(diffInMillis);  // 转换为秒
        long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(diffInMillis);  // 转换为分钟
        long diffInHours = TimeUnit.MILLISECONDS.toHours(diffInMillis);  // 转换为小时
        long diffInDays = TimeUnit.MILLISECONDS.toDays(diffInMillis);  // 转换为天

        if (diffInSeconds < 60) {
            return "刚刚";
        } else if (diffInMinutes < 60) {
            return diffInMinutes + "分钟前";
        } else if (diffInHours < 24) {
            return diffInHours + "小时前";
        } else if (diffInDays < 30) {
            return diffInDays + "天前";
        } else {
            return "30天前";
        }
    }
}
